package com.bifang.core.dict.integration.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bifang.common.constant.CacheConst;
import com.bifang.common.constant.enums.common.BoolEnum;
import com.bifang.common.constant.enums.common.FuncTypeEnum;
import com.bifang.common.exception.AppException;
import com.bifang.common.util.PagerUtil;
import com.bifang.common.helper.RedisHelper;
import com.bifang.common.vo.CommonDeleteVO;
import com.bifang.common.vo.CommonDetailVO;
import com.bifang.common.vo.CommonVO;
import com.bifang.common.annotations.OpApi;
import com.bifang.core.dao.model.SysCommon;
import com.bifang.core.dao.service.SysCommonService;
import com.bifang.core.dict.integration.CommonIntegration;
import com.bifang.core.dict.integration.DictIntegration;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * 系统通用参数实现类
 *
 * @author chenzh
 * @date 2018-08-14
 */
@Service
public class CommonIntegrationImpl implements CommonIntegration {
    private static final String CACHE_COMMON = "common";
    @Autowired
    RedisHelper redisHelper;
    @Autowired SysCommonService sysCommonService;
    @Autowired DictIntegration dictIntegration;

    @Override
    @OpApi(
            funcCode = "COMMON0001",
            title = "根据条件查询系统参数",
            funcType = FuncTypeEnum.query,
            savelog = false)
    public PageInfo<CommonVO> getCommonList(CommonVO commonVO) {
        SysCommon sysCommon = Convert.convert(SysCommon.class, commonVO);
        sysCommon.setParamKey(null);
        sysCommon.setParamName(null);
        sysCommon.setParamValue(null);
        QueryWrapper<SysCommon> queryWrapper = new QueryWrapper<>(sysCommon);
        queryWrapper.lambda().eq(SysCommon::getDel, BoolEnum.FALSE.getType());
        if (StringUtils.isNotBlank(commonVO.getParamKey())) {
            queryWrapper.lambda().like(SysCommon::getParamKey, commonVO.getParamKey());
        }
        if (StringUtils.isNotBlank(commonVO.getParamName())) {
            queryWrapper.lambda().like(SysCommon::getParamName, commonVO.getParamName());
        }
        if (StringUtils.isNotBlank(commonVO.getParamValue())) {
            queryWrapper.lambda().like(SysCommon::getParamValue, commonVO.getParamValue());
        }

        Integer pageNum = commonVO.getPageNum();
        Integer pageSize = commonVO.getPageSize();
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }

        List<SysCommon> sysCommonList = sysCommonService.list(queryWrapper);
        if (CollectionUtils.isEmpty(sysCommonList)) {
            return PagerUtil.createEmptyPagerInfo(pageNum, pageSize);
        }
        PageInfo<SysCommon> sysCommonPageInfo = new PageInfo<>(sysCommonList);
        List<CommonVO> commonVOList = new ArrayList<>();
        for (SysCommon common : sysCommonPageInfo.getList()) {
            CommonVO vo = Convert.convert(CommonVO.class, common);
            // 转义中文
            vo.setOrgName(dictIntegration.getOrgNameById(common.getOrgId()));
            commonVOList.add(vo);
        }

        return PagerUtil.parsePagerVo(commonVOList, sysCommonPageInfo);
    }

    @Override
    public String getValueByKey(String paramKey) {
        if (StringUtils.isBlank(paramKey)) {
            return "";
        }
        Object obj = redisHelper.hget(CacheConst.SYSTEM_PARAMS + CACHE_COMMON, paramKey);
        if (obj != null) {
            return obj.toString();
        }
        QueryWrapper<SysCommon> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysCommon::getDel, BoolEnum.FALSE.getType());
        queryWrapper.lambda().eq(SysCommon::getStatus, BoolEnum.TRUE.getType());
        queryWrapper.lambda().eq(SysCommon::getParamKey, paramKey);

        List<SysCommon> sysCommonList = sysCommonService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(sysCommonList)) {
            String value = sysCommonList.get(0).getParamValue();
            redisHelper.hset(CacheConst.SYSTEM_PARAMS + CACHE_COMMON, paramKey, value);
            return value;
        }
        return "";
    }

    @Override
    public String getValueByKeyAndClassify(String paramKey, String classify) {
        if (StringUtils.isBlank(paramKey)) {
            return "";
        }
        String key = paramKey + classify;
        Object obj = redisHelper.hget(CacheConst.SYSTEM_PARAMS + CACHE_COMMON, key);
        if (obj != null) {
            return obj.toString();
        }
        QueryWrapper<SysCommon> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(SysCommon::getDel, BoolEnum.FALSE.getType())
                .eq(SysCommon::getStatus, BoolEnum.TRUE.getType())
                .eq(SysCommon::getParamKey, paramKey);
        if (StringUtils.isNotBlank(classify)) {
            queryWrapper.lambda().eq(SysCommon::getClassify, classify);
        }
        List<SysCommon> sysCommonList = sysCommonService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(sysCommonList)) {
            String value = sysCommonList.get(0).getParamValue();
            redisHelper.hset(CacheConst.SYSTEM_PARAMS + CACHE_COMMON, key, value);
            return value;
        }
        return "";
    }

    @Override
    @OpApi(
            funcCode = "COMMON0003",
            title = "根据ID查询详情",
            funcType = FuncTypeEnum.query,
            savelog = false)
    public CommonVO getSystemParamDetail(CommonDetailVO commonDetailVO) {
        return getSystemParamById(commonDetailVO.getSysId());
    }

    @Override
    public CommonVO getSystemParamById(Long sysId) {
        if (sysId == null) {
            throw new AppException("sysId不能为空");
        }
        SysCommon sysCommon = sysCommonService.getById(sysId);
        if (sysCommon == null) {
            throw new AppException("找不到系统参数信息");
        }
        CommonVO commonVO = Convert.convert(CommonVO.class, sysCommon);
        return commonVO;
    }

    @Override
    @OpApi(funcCode = "COMMON0004", title = "新增系统参数", funcType = FuncTypeEnum.insert)
    public CommonVO add(CommonVO commonVO) {
        if (commonVO.getSysId() != null) {
            throw new AppException("新增参数ID必须为空");
        }
        checkParamKey(commonVO);
        checkParamName(commonVO);
        SysCommon sysCommon = Convert.convert(SysCommon.class, commonVO);
        if (StringUtils.isNotBlank(commonVO.getOrgId())) {
            sysCommon.setOrgNumber(dictIntegration.getOrgCodeById(commonVO.getOrgId()));
        }
        sysCommonService.save(sysCommon);
        return getSystemParamById(sysCommon.getSysId());
    }

    @Override
    @OpApi(funcCode = "COMMON0005", title = "修改系统参数", funcType = FuncTypeEnum.update)
    public CommonVO edit(CommonVO commonVO) {
        SysCommon sysCommon = sysCommonService.getById(commonVO.getSysId());
        if (sysCommon == null) {
            throw new AppException("未找到需要修改的数据");
        }
        if (BoolEnum.TRUE.getType().equals(sysCommon.getDel())) {
            throw new AppException("该数据已被删除");
        }
        if (!commonVO.getParamKey().equals(sysCommon.getParamKey())) {
            checkParamKey(commonVO);
        }
        if (!commonVO.getParamName().equals(sysCommon.getParamName())) {
            checkParamName(commonVO);
        }
        BeanUtil.copyProperties(commonVO, sysCommon);
        if (StringUtils.isNotBlank(commonVO.getOrgId())) {
            sysCommon.setOrgNumber(dictIntegration.getOrgCodeById(commonVO.getOrgId()));
        }
        sysCommonService.saveOrUpdate(sysCommon);
        return getSystemParamById(sysCommon.getSysId());
    }

    private void checkParamKey(CommonVO commonVO) {
        if (StringUtils.isNotBlank(commonVO.getParamKey())) {
            QueryWrapper<SysCommon> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysCommon::getDel, BoolEnum.FALSE.getType());
            queryWrapper.lambda().eq(SysCommon::getStatus, BoolEnum.TRUE.getType());
            queryWrapper.lambda().eq(SysCommon::getParamKey, commonVO.getParamKey());
            List<SysCommon> list = sysCommonService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(list)) {
                throw new AppException("参数标识重复");
            }
        }
    }

    private void checkParamName(CommonVO commonVO) {
        if (StringUtils.isNotBlank(commonVO.getParamName())) {
            QueryWrapper<SysCommon> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysCommon::getDel, BoolEnum.FALSE.getType());
            queryWrapper.lambda().eq(SysCommon::getStatus, BoolEnum.TRUE.getType());
            queryWrapper.lambda().eq(SysCommon::getParamName, commonVO.getParamName());
            List<SysCommon> list = sysCommonService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(list)) {
                throw new AppException("参数名称重复");
            }
        }
    }

    @Override
    @OpApi(funcCode = "COMMON0006", title = "单个删除系统参数", funcType = FuncTypeEnum.delete)
    public void delete(CommonDeleteVO commonVO) {
        SysCommon sysCommon = sysCommonService.getById(commonVO.getSysId());
        if (sysCommon == null) {
            throw new AppException("未找到需要删除的数据");
        }
        if (BoolEnum.TRUE.getType().equals(sysCommon.getDel())) {
            throw new AppException("该数据已被删除");
        }
        UpdateWrapper<SysCommon> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .lambda()
                .set(SysCommon::getDel, BoolEnum.TRUE.getType())
                .eq(SysCommon::getSysId, commonVO.getSysId());
        sysCommonService.update(updateWrapper);
        this.clearCache(sysCommon.getParamKey());
    }

    @Override
    @OpApi(funcCode = "COMMON0007", title = "批量删除系统参数", funcType = FuncTypeEnum.delete)
    public void deleteBatch(CommonDeleteVO commonVO) {
        if (CollectionUtils.isEmpty(commonVO.getSysIds())) {
            throw new AppException("参数ID不能传空");
        }
        QueryWrapper<SysCommon> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .in(SysCommon::getSysId, commonVO.getSysIds())
                .eq(SysCommon::getDel, BoolEnum.FALSE.getType());
        List<SysCommon> list = sysCommonService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            throw new AppException("未找到需要删除的数据");
        }
        for (SysCommon sysCommon : list) {
            sysCommonService.removeByIds(commonVO.getSysIds());
            this.clearCache(sysCommon.getParamKey());
        }
        sysCommonService.updateBatchById(list);
    }

    @Override
    @OpApi(
            funcCode = "COMMON0008",
            title = "系统参数清除缓存",
            funcType = FuncTypeEnum.other,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public void clearCache(CommonVO commonVO) {
        String paramKey = commonVO.getParamKey();
        this.clearCache(paramKey);
    }

    private void clearCache(String paramKey) {
        if (StringUtils.isNotBlank(paramKey)) {
            redisHelper.hdel(CacheConst.SYSTEM_PARAMS + CACHE_COMMON, paramKey);
        } else {
            redisHelper.del(CacheConst.SYSTEM_PARAMS + CACHE_COMMON);
        }
    }
}
